package cn.com.captureNetPacket.controller;

import cn.com.captureNetPacket.CaptureNetPacketService;
import cn.com.captureNetPacket.util.FileUtils;
import cn.com.captureNetPacket.util.RedisConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.com.captureNetPacket.model.ParamCondition;
import cn.com.captureNetPacket.model.RecordLog;
import cn.com.captureNetPacket.model.WebResult;
import cn.com.captureNetPacket.service.RecordLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/if/capture/record")
@Api(value = "RecordLogController", tags = { "RecordLogController" }, description = "RECORDLOG相关")
public class RecordLogController {

	@Autowired
	private RecordLogService recordLogService;
	
	@Autowired
	private ObjectMapper mapper;
	//文件保存路径
	@Value("${file.localRecordPath}")
	private String localRecordPath;
	@Value("${file.originSavePath}")
	private String originSavePath;
	@GetMapping("/getAll")
	@ApiOperation("查询RECORDLOG表中所有数据")
	public Object getAllRecordLog() throws JsonProcessingException {
		WebResult ws = recordLogService.searchAll();
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}

	@GetMapping("/getAllByPaging/{currentPage}/{size}")
	@ApiOperation("分页查询RECORDLOG表中数据")
	public Object getAllRecordLogByPaging(@PathVariable(name = "currentPage") int currentPage,
			@PathVariable(name = "size") int size) throws JsonProcessingException {
		WebResult ws = recordLogService.searchByPaging(currentPage, size);
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}
	
	@PostMapping("/addRecordLog")
	@ApiOperation("添加数据到RECORDLOG表")
	public Object addRecordLog(@RequestBody RecordLog recordLog) throws JsonProcessingException {
		log.debug("---上送参数为:{}-----",recordLog);
		WebResult ws = recordLogService.create(recordLog);
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}

	
	@DeleteMapping("/removeRecordLog")
	@ApiOperation("根据id删除RECORDLOG表中数据")
	public Object removeRecordLog(@RequestBody RecordLog recordLog) throws JsonProcessingException {
		log.debug("---上送参数为:{}-----",recordLog);
		WebResult ws = recordLogService.remove(recordLog);
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}
	
	@PatchMapping("/modifyRecordLog")
	@ApiOperation("根据id修改RECORDLOG表中数据")
	public Object modifyRecordLog(@RequestBody RecordLog recordLog) throws JsonProcessingException {
		log.debug("---上送参数为:{}-----",recordLog);
		WebResult ws = recordLogService.modify(recordLog);
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}
	
	@PostMapping("/getRecordLogByConditionAndPaging")
	@ApiOperation("分页+条件查询RECORDLOG表中数据")
	public Object getRecordLogByConditionAndPaging(@RequestBody ParamCondition<RecordLog> paramCondition)
			throws JsonProcessingException {
		log.debug("---上送参数为:{}-----", mapper.writeValueAsString(paramCondition));
		WebResult ws = recordLogService.searchByCondition(paramCondition.getCurrentPage(), paramCondition.getSize(),
				paramCondition);
		log.debug("---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}




	@GetMapping("/getRecords")
	@ApiOperation("条件查询录音文件")
	public Object getRecords(@RequestParam(value = "id",required = false) String id,
							@RequestParam(value = "callId",required = false) String callId,
							@RequestParam(value = "callUUID",required = false) String callUUID,
							@RequestParam(value = "fromUser",required = false) String fromUser,
							@RequestParam(value = "toUser",required = false) String toUser,
							@RequestParam(value = "caller",required = false) String caller,
							@RequestParam(value = "agentID",required = false) String agentID,
							@RequestParam(value = "called",required = false) String called,
							@RequestParam(value = "deviceNumber",required = false) String deviceNumber,
							 @RequestParam(value = "page",required = false,defaultValue = "1") Integer page,
							 @RequestParam(value = "size",required = false,defaultValue = "20") Integer size
							)
			throws JsonProcessingException {
		RecordLog recordLog=new RecordLog();
		recordLog.setId(id);
		recordLog.setCallId(callId);
		recordLog.setCallUUID(callUUID);
		recordLog.setFromUser(fromUser);
		recordLog.setToUser(toUser);
		recordLog.setCaller(caller);
		recordLog.setAgentID(agentID);
		recordLog.setCalled(called);
		recordLog.setDeviceNumber(deviceNumber);
		ParamCondition<RecordLog> paramCondition=new ParamCondition<>();
		paramCondition.setEntity(recordLog);
		if(page>0){
			paramCondition.setCurrentPage(page);
		}else {
			paramCondition.setCurrentPage(1);
		}
		if(size>0){
			paramCondition.setSize(size);
		}else {
			paramCondition.setSize(20);
		}
		log.debug("条件查询录音文件---上送参数为:{}-----", mapper.writeValueAsString(paramCondition));
		WebResult ws = recordLogService.searchByCondition(paramCondition.getCurrentPage(), paramCondition.getSize(),
				paramCondition);
		log.debug("条件查询录音文件---返回数据:---->{}", mapper.writeValueAsString(ws));
		return ws;
	}




	@GetMapping("/getRecordFile")
	@ApiOperation("条件查询录音文件")
	public Object getRecordFile(@RequestParam(value = "id",required = false) String id,
							@RequestParam(value = "callId",required = false) String callId,
							@RequestParam(value = "callUUID",required = false) String callUUID,
							@RequestParam(value = "fromUser",required = false) String fromUser,
							@RequestParam(value = "toUser",required = false) String toUser,
							@RequestParam(value = "caller",required = false) String caller,
							@RequestParam(value = "agentID",required = false) String agentID,
							@RequestParam(value = "called",required = false) String called,
							@RequestParam(value = "deviceNumber",required = false) String deviceNumber,
							@RequestParam(value = "queryLocal",required = false,defaultValue = "false") Boolean queryLocal,
							@RequestParam(value = "page",required = false,defaultValue = "1") Integer page,
							@RequestParam(value = "size",required = false,defaultValue = "20") Integer size,
							HttpServletRequest request,
							HttpServletResponse response
							)
			throws JsonProcessingException {
		RecordLog recordLog=new RecordLog();
		recordLog.setId(id);
		recordLog.setCallId(callId);
		recordLog.setCallUUID(callUUID);
		recordLog.setFromUser(fromUser);
		recordLog.setToUser(toUser);
		recordLog.setCaller(caller);
		recordLog.setAgentID(agentID);
		recordLog.setCalled(called);
		recordLog.setDeviceNumber(deviceNumber);
		ParamCondition<RecordLog> paramCondition=new ParamCondition<>();
		paramCondition.setEntity(recordLog);
		if(page>0){
			paramCondition.setCurrentPage(page);
		}else {
			paramCondition.setCurrentPage(1);
		}
		if(size>0){
			paramCondition.setSize(size);
		}else {
			paramCondition.setSize(20);
		}
		log.debug("条件查询录音文件---上送参数为:{}-----", mapper.writeValueAsString(paramCondition));
		WebResult ws = recordLogService.searchByCondition(paramCondition.getCurrentPage(), paramCondition.getSize(),
				paramCondition);

		Assert.notNull(ws.getData(),"查询数据不能为空");
		List<RecordLog> recordLogs  = ((Map<String, List<RecordLog>>) ws.getData()).get("info");
		RecordLog rl=null;
		 try {
				if(recordLogs.size()<1){
					throw new Exception("查询记录为空");
				}
			 rl=recordLogs.get(0);
			if(!StringUtils.hasText(rl.getRecordPath())){
				throw new Exception("录音记录存在，但url为空");
			}

			String recordPathTemp=rl.getRecordPath().substring(originSavePath.length()+1,rl.getRecordPath().length());
			String dirName=recordPathTemp.substring(0,8);
			String fileName=recordPathTemp.substring(9,recordPathTemp.length());
			String returnFileName=dirName+"_"+fileName;
			log.info("父级目录和文件名: {}  父级目录文件夹名: {}, 文件名: {}",recordPathTemp,dirName,fileName);
			 String recordFilePath=localRecordPath+File.separator+dirName+File.separator+fileName;
			 Properties sysProperties = CaptureNetPacketService.props;
			 File recordFile=new File(recordFilePath);
				if(recordFile.exists()){
					response.setContentType("audio/wav;charset=UTF-8");
					response.setHeader("Content-Disposition", "attachment;filename=" +returnFileName+ ".wav");
					FileUtils.responseFile(response,recordFile);
					log.debug("本地已经获取到文件，父级目录和文件名: {}  父级目录文件夹名: {}, 文件名: {}",recordPathTemp,dirName,fileName);
					return null;
				}
				if(queryLocal){
					log.debug("参数关闭了远程服务器下载录音的参数: 录音记录:{}   录音的路径: {}", rl, recordFilePath);
					response.setStatus(HttpStatus.GATEWAY_TIMEOUT.value());
					ws.setRetcode("404");
					ws.setErrorMsg("本地路径未找到录音文件。当前服务器信息: "+CaptureNetPacketService.getCurrentRecordUri());
					return ws;
				}else {
					log.debug("开启了远程服务器下载的参数。查询当前服务器未找到录音文件，需要去其他服务器上下载: 录音记录:{}   录音的路径: {}", rl, recordFilePath);
				}
			 String targetResquestUri = request.getRequestURI().substring(request.getServletContext().getContextPath().length());
				String queryString=request.getQueryString().replace("queryLocal=","");
			 log.debug("请求其他服务器参数.--->>>>uri:{}    查询参数: {}",targetResquestUri,queryString);
			 File parentDir=new File(localRecordPath+File.separator+dirName+File.separator);

			 if(!parentDir.exists()){
				 parentDir.mkdirs();
			 }
			 File tempfile = new File(parentDir.getAbsolutePath()+File.separator+fileName);

			 log.debug("将会缓存到文件: {}",tempfile.getAbsolutePath());
			 Set<String> keys= RedisConfig.getkeys("recordUri:");
			 if(keys!=null) {
				 for (String key:keys){
								 String tempUri = RedisConfig.getRealKeyValue(key);
								 // 判断是否为本机的uri，避免循环调用。
								 if (!tempUri.equals(CaptureNetPacketService.getCurrentRecordUri())) {
									 //   添加只查询本地的参数，避免其他机器调用其他的服务器的情况。
									 String url = "http://" + tempUri + targetResquestUri + "?queryLocal=true&" + queryString;
									 log.debug("正在获取远程服务路径、key-> {} 正在下载url: {}", key, url);
									 FileUtils.downloadNetWorkFileAsMedia(url, tempfile, new HashMap<>(), 1);
									 if (tempfile.exists() && tempfile.length() > 0) {
										 response.setContentType("audio/wav;charset=UTF-8");
										 response.setHeader("Content-Disposition", "attachment;filename=" + returnFileName + ".wav");
										 FileUtils.responseFile(response, tempfile);
										 log.debug("已经获取远程服务服务器的文件返回。key-> {} 正在下载url: {}", key, url);
										 return null;
									 }
								 }

			 }
			 }
		 }catch (Exception e){
		 	log.warn("查询录音结果失败: {}",paramCondition,e);
			 ws.setErrorMsg(e.getMessage());
			 ws.setRetcode("9999");
			 response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
			 response.setStatus(404);
			 return ws;
		 }
		ws.setRetcode("404");
		ws.setErrorMsg("录音文件未能找到");
		return ws;
	}

}
